package org.languageguide.readings;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.languageguide.storage.DBConnector;

/* Wraps sentences in spans with (class="sentence")
 *  
 *  Expects Latin character style punctuation found in English or other European language 
 *  
 */

public class StandardSentenceWrapper implements SentenceWrapper {

	private int location = 0;
	int sentenceCounter = 0;
	private List<Entity> paragraphs;

	public String wrap(String toPrepare){
		loadDocumentIntoParagraphsAndSentences(toPrepare);
		return generateText();
	}
	
	public List<Entity> getParagraphsAndSentences(String toPrepare){
		loadDocumentIntoParagraphsAndSentences(toPrepare);
		return paragraphs;
	}

	public void storeSentencesInDb(Integer readingId){
		DBConnector connector = DBConnector.getInstance();
		Connection connection = connector.getConnection();
		try {
			connection.setAutoCommit(false);
			String sql = "INSERT INTO ReadingSentences(Paragraph, SentenceOrder, Sentence, ReadingId) VALUES(?, ?, ?, ?)";
			PreparedStatement pstmt = connection.prepareStatement(sql);
			int paragraphCount = 1;
			int sentenceCount = 1;
			for (Entity entity: paragraphs){
				List<String> sentences = entity.getSentences();
				for (String sentence: sentences){
					//sentence = "P.S. Si vous me donnez ladresse de Monsieur Crisse, je lui enverrai une carte postale.";
					//sentence = "test";
					//
					// Create a prepared statement


					// Insert 10 rows of data
			
					pstmt.setInt(1, paragraphCount);
					pstmt.setInt(2, sentenceCount);
					pstmt.setString(3, sentence);
					pstmt.setInt(4, readingId);
					pstmt.addBatch();
					sentenceCount++;
				}
				paragraphCount++;
			}
			pstmt.executeBatch();
			connection.setAutoCommit(true);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}


	}
	
	


	private String generateText(){
		StringBuilder text = new StringBuilder();
		for (Entity entity: paragraphs){
			List<String> sentences = entity.getSentences();
			text.append(entity.getStartTag());
			if (sentences !=null){
				for (String sentence: sentences){
					text.append("<span id=\"s" + sentenceCounter  + "\">");
					text.append(sentence);
					text.append("</span> ");
					sentenceCounter++;
				}
			}
			text.append(entity.getEndTag());
		}
		return text.toString();
	}

	public Integer getSentenceCount(){
		return sentenceCounter;
	}

	public Header processHeaderAndAdvanceLocation(StringBuilder builder) throws Exception{
		StringBuilder sentence = new StringBuilder();
		while (hasMore(location, builder)){
			char i = builder.charAt(location);
			if (i == '<'){ // check to see if we've encounted a paragraph tag.
				String tagName = retrieveTagNameAndAdvanceLocation(builder);
				if (tagName.equals("/header")){
					Header paragraph = new Header(sentence.toString());
					return paragraph;
				}
				else {
					throw new Exception("Tag inside header");
				}
			}
			else sentence.append(i);
			location++;
		}

		// if you get here it means that the paragraph isn't closed with a </p>
		// let's return the sentences for now - it might be better to throw an exception
		throw new Exception("Document doesn't have closing </header>");
	}

	public Image processImageAndAdvanceLocation(StringBuilder builder) throws Exception{
		StringBuilder tag = new StringBuilder("<img ");
		while (hasMore(location, builder)){
			char i = builder.charAt(location);
			tag.append(i);
			if (i == '>'){ 
				Image image = new Image(tag.toString());
				return image;
			}
			location++;
		}

		// if you get here it means that the paragraph isn't closed with a </p>
		// let's return the sentences for now - it might be better to throw an exception
		throw new Exception("Document doesn't have closing </header>");
	}


	private void loadDocumentIntoParagraphsAndSentences(String toPrepare){
		StringBuilder builder = new StringBuilder(toPrepare);
		paragraphs = new ArrayList<Entity>();
		while (hasMore(location, builder)){
			char i = builder.charAt(location);
			if (i == '<'){
				String tagName = retrieveTagNameAndAdvanceLocation(builder);
				if (tagName.equals("p")){

					try {
						Entity paragraph = processParagraphAndAdvanceLocation(builder);
						paragraphs.add(paragraph);
					} catch (Exception e) {
						System.out.println("exception" + e);
						e.printStackTrace();
						return;
					}
				}
				else if (tagName.equals("header")){
					try {
						Header header = processHeaderAndAdvanceLocation(builder);
						paragraphs.add(header);
					} catch (Exception e) {
						System.out.println("exception" + e);
						e.printStackTrace();
						return;
					}
				}
				else if (tagName.equals("img")){
					try {
						Image image = processImageAndAdvanceLocation(builder);
						paragraphs.add(image);
					} catch (Exception e) {
						System.out.println("exception" + e);
						e.printStackTrace();
						return;
					}
				} 
				else{
					location++;
				}
			}
			else{
				location++;
			}
		}
	}

	private boolean hasMore(int location, StringBuilder builder){
		if (location < builder.length())
			return true;
		else return false;
	}

	/**
	 * Throws an exception if paragraph is not closed with a </p>
	 * 
	 * @param builder
	 * @return
	 * @throws Exception
	 */
	private Entity processParagraphAndAdvanceLocation(StringBuilder builder) throws Exception{
		List<String> sentences = new ArrayList<String>();
		StringBuilder sentence = new StringBuilder();
		while (hasMore(location, builder)){
			char i = builder.charAt(location);
			if (i == '<'){ // check to see if we've encounted a paragraph tag.
				String tagName = retrieveTagNameAndAdvanceLocation(builder);
				if (tagName.equals("/p")){
					if (sentences.size() != 0){
						Paragraph paragraph = new Paragraph(sentences);
						return paragraph;	
					}
					else{
						Header header = new Header(sentence.toString());
						return header;
					}
				}
				if (tagName.equals("p")){
					throw new Exception("Paragraphh doesn't have closing </p>");
				}
			}
			else if (isPunctuation(i) && notPartOfAbreviationOrNumber(builder)){ // , i
				sentence.append(i);
				//peek ahead and see if it's a quote
				i = builder.charAt(location + 1);
				if (i == '"'){
					sentence.append(i);
					location++;
				}
				sentences.add(sentence.toString().trim());
				sentence = new StringBuilder();
				//location++; // skip over space that comes after punctuation
			}
			else if (i == ' '){
				if (abreviationEncountered)
					abreviationEncountered = false;
				sentence.append(i);
			}
			else sentence.append(i);
			location++;
		}

		// if you get here it means that the paragraph isn't closed with a </p>
		// let's return the sentences for now - it might be better to throw an exception
		throw new Exception("Document doesn't have closing </p>");
		//return sentences;
	}

	private boolean isPunctuation(int i){
		if (i == '.' || i == '?' || i == ';' || i == '!'){// || i == '。' || i == '！' || i == '；' || i == '؟' || i == '？'){
			return true;
		}
		else return false;
	}

	boolean abreviationEncountered = false;;
	public boolean notPartOfAbreviationOrNumber(StringBuilder builder){ // , char i
		//if (abreviationEncountered &&  (i != '?' && i != ';' && i != '!'))
		//	return true;
		return true;
		/*if (!abreviationEncountered){
			char characterAfterPunctuation = builder.charAt(location + 1);
			if (characterAfterPunctuation == ' ' || characterAfterPunctuation == '<'  || characterAfterPunctuation == '"'){
				return true;
			}
			abreviationEncountered = true;
		}
		return false;*/
	}


	private String retrieveTagNameAndAdvanceLocation(StringBuilder builder){
		location = location + 1;
		char cha = builder.charAt(location);
		StringBuilder tag = new StringBuilder(""); 
		while (cha == ' '){
			location++;	
			cha = builder.charAt(location);
		}
		while (cha != ' ' && cha != '>'){
			tag.append(cha);
			//System.out.println(tag);
			location++;	
			cha = builder.charAt(location);
		}
		location++;
		return tag.toString();
	}




	public static void main(String[] args){
	//	String paragraph = "<p>Although the Yapese people usually spend U.S. dollars, their traditional money, the Rai, is actually made of stone.</p> ";
//		String paragraph = "<p>And the teacher said, \"But nobody knows what God looks like.\" And the girl said, \"They will in a minute.\"</p>";
		String paragraph = "<p>Pero cuándo te invitan, y hablas con alguien sabes, te dicen, \"¿En qué trabajas?\" Y dices que trabajas en educación, puedes ver que se ponen pálidos.</p>";
		SentenceWrapper wrapper = new StandardSentenceWrapper();
		String processed = wrapper.wrap(paragraph);
		System.out.println(processed);
	}


}
